// 支持受控和非受控模式

// 受控模式下需要手动触发input的组件更新，
import {
  ChangeEvent,
  forwardRef,
  ForwardRefRenderFunction,
  useImperativeHandle,
  useRef,
  KeyboardEvent,
  FocusEvent,
} from "react";
import "./index.scss";
import cs from "classnames";

interface TInputProps {
  value?: string;
  defaultValue?: string;
  onChange?: (value: string) => void;
  onEnter?: (value: string) => void;
  placeholder?: string;
  classNames?: string | string[];
  onFocus?: (prop: FocusEvent<HTMLInputElement>) => void;
  onBlur?: () => void;
}

export interface InpRef {
  value?: string;
}

const TInput: ForwardRefRenderFunction<InpRef, TInputProps> = (props, ref) => {
  const {
    value,
    defaultValue,
    onChange,
    onEnter,
    placeholder,
    classNames = [],
    onFocus,
    onBlur,
  } = props;
  const inpRef = useRef<HTMLInputElement>(null);
  const isControlled = "value" in props;

  useImperativeHandle(
    ref,
    () => {
      return {
        get value() {
          return inpRef.current?.value;
        },
      };
    },
    [inpRef]
  );

  function handleChange(e: ChangeEvent<HTMLInputElement>) {
    onChange?.(e.target.value);
  }

  function handleEnter(e: KeyboardEvent<HTMLInputElement>) {
    if (e.code === "Enter") {
      // currentTarget 只存在于事件触发到事件处理结束之间，随后就重置为 null 了
      // 同步代码可以获取到currentTarget，异步为null
      onEnter?.(e.currentTarget.value);
    }
  }
  return (
    <>
      {isControlled ? (
        <input
          className={cs(["t-input", classNames])}
          type="text"
          value={value || ""}
          onChange={handleChange}
          onKeyDown={handleEnter}
          placeholder={placeholder}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      ) : (
        <input
          type="text"
          className={cs(["t-input", classNames])}
          ref={inpRef}
          defaultValue={defaultValue}
          onChange={handleChange}
          onKeyDown={handleEnter}
          placeholder={placeholder}
          onFocus={onFocus}
          onBlur={onBlur}
        />
      )}
    </>
  );
};

export default forwardRef(TInput);
